/*
 * @(#)UUIDUtils.java
 * Date 2013-08-17
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.utils;

import java.math.BigInteger;

import java.text.ParseException;

import java.util.UUID;

import org.apache.commons.lang3.StringUtils;


/**
 * Class description
 *
 *
 * @version        v1.0, 2013-08-17
 * @author         Jim Horner
 */
public class UUIDUtils {

    /** Field description */
    public static final String OID_ROOT = "2.25";

    /** Field description */
    public static final String URN_PREFIX = "urn:uuid:";

    /**
     * Method description
     *
     *
     * @param uuidstr
     *
     * @return
     */
    public static String createURN(String uuidstr) {

        return String.format("%s%s", URN_PREFIX, uuidstr);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public static String generate() {

        return UUID.randomUUID().toString().toLowerCase();
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public static String generateOID() {

        return toOID(UUID.randomUUID());
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public static String generateURN() {

        return createURN(UUID.randomUUID().toString().toLowerCase());
    }

    /**
     * Method description
     *
     *
     * @param uuidstr
     *
     * @return
     */
    public static boolean isNotValidWithURN(String uuidstr) {

        return (isValidWithURN(uuidstr) == false);
    }

    /**
     * Method description
     *
     *
     * @param uuidstr
     *
     * @return
     */
    public static boolean isValid(String uuidstr) {

        boolean result = false;

        try {

            String teststr = removeURNPrefix(uuidstr);

            if (StringUtils.isNotBlank(teststr)) {

                UUID.fromString(teststr);

                result = true;
            }

        } catch (IllegalArgumentException e) {

            // don't care
        }

        return result;
    }

    /**
     * Method description
     *
     *
     * @param uuidstr
     *
     * @return
     */
    public static boolean isValidWithURN(String uuidstr) {

        boolean result = false;

        if (StringUtils.startsWith(uuidstr, URN_PREFIX)) {

            result = isValid(uuidstr);
        }

        return result;
    }

    /**
     * Method description
     *
     *
     * @param uuidstr
     *
     * @return
     */
    public static String removeURNPrefix(String uuidstr) {

        return StringUtils.remove(uuidstr, URN_PREFIX);
    }

    /**
     * IHE_ITI_TF_Rev7-0_Vol2x_FT_2010-08-10<br />
     * B.6: Representing UUIDs as OIDs<br />
     * The standards ITU X.667 and ISO 9834-8 defined a particular OID root
     * for the UUIDs, and define the translation between these two formats.
     * The top node 2.25 is assigned for all UUIDs. This means that the UUID
     * that can be written as urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6
     * (using hexadecimal notation) is also
     * 2.25.329800735698586629295641978511506172918 (using dotted decimal
     * notation).
     *
     * @param uuid
     *
     * @return
     */
    public static String toOID(UUID uuid) {

        return toOID(uuid, OID_ROOT);
    }

    /**
     * Method description
     *
     *
     * @param uuid
     * @param prefix
     *
     * @return
     */
    public static String toOID(UUID uuid, String prefix) {

        String result = null;

        if ((uuid != null) && StringUtils.isNotBlank(prefix)) {

            String uuidstr = uuid.toString().replaceAll("-", "");
            BigInteger bi = new BigInteger(uuidstr, 16);

            result = String.format("%s.%s", prefix, bi.toString());
        }

        return result;
    }

    /**
     * Method description
     *
     *
     * @param uuidstr
     *
     * @return
     *
     * @throws ParseException
     */
    public static String toOIDFromUUIDString(String uuidstr) throws ParseException {

        return toOIDFromUUIDString(removeURNPrefix(uuidstr), OID_ROOT);
    }

    /**
     * Method description
     *
     *
     * @param uuidstr
     * @param prefix
     *
     * @return
     *
     * @throws ParseException
     */
    public static String toOIDFromUUIDString(String uuidstr, String prefix)
            throws ParseException {

        String result = null;

        try {

            UUID uuid = UUID.fromString(uuidstr);

            result = toOID(uuid, prefix);

        } catch (IllegalArgumentException e) {

            throw new ParseException(String.format("String[%s] is not a UUID.", uuidstr),
                                     0);
        }

        return result;
    }
}
